//
//  "$Id: AudioDec.h 91958 2012-12-10 05:51:16Z wang_haifeng $"
//
//  Copyright (c)1992-2007, ZheJiang Dahua Technology Stock CO.LTD.
//  All Rights Reserved.
//
//	Description:	
//	Revisions:		Year-Month-Day  SVN-Author  Modification
//

#ifndef __AUDIO_DEC_API_H__
#define __AUDIO_DEC_API_H__

#include "Types.h"
#include "AudioIn.h"
#include "AudioEnc.h"

#ifdef __cplusplus
extern "C" {
#endif

/// \defgroup AudioDecAPI API Audio Decoder
/// 音频解码接口，音频解码用于回放，语音对讲，语音提示等多种场合。
/// \n 调用流程图:
/// \code
///    ==========================================
///               |
///	      createAudioDecorder
///               |
///            addRef
///               |-----------------+
///             start               |
///               |---------+    setVolume
///           putBuffer     |       |
///               |---------+       |
///             stop                |
///               |-----------------+
///            release
///               |
///    ==========================================
/// \endcode
/// @{

enum AudioEncType;
enum AudioEncPackType;

/// 输出声音质量增强功能
typedef enum AudioOutVqeType
{
	audioOutVqeHpf = 0,	///< 高通滤波
	audioOutVqeAnr,		///< 降噪功能
	audioOutVqeAgc,		///< 自动增益
} AudioOutVqeType;

///输出音质增强, 128字节
typedef struct
{
	int enableAnr;		///< 是否开启降噪功能, 1-开启， 0-不开启
	int enableAlc;		///< 是否开启自动增益, 1-开启， 0-不开启
	int enableHpf;		///< 是否开启高通滤波, 1-开启， 0-不开启
	int	reserved[29];	///< 保留
}AudioOutVqeAttr;

/// 解码的压缩数据帧结构，128字节
typedef struct AudioDecFormat
{
	AudioEncType		type;		///< 音频编码的类型
	int					frequency;	///< 采样率，Hz为单位，比如44100Hz	
	char				depth;		///< 采样位深，支持8位，16位
	unsigned int        channels;   ///< 音频通道数
	char				mode;	///< 工作模式，不同编码类型定义不同。
	char 				reserved1[2]; ///< 保留
	AudioEncPackType	pack;		///< 打包格式
	int reserved[28];				///< 保留
} AudioDecFormat;

/// 音频解码数据包结构，128字节
typedef struct AudioDecPacket
{
	/// 待写入的帧数据缓冲指针，音频帧都包括大华帧头，多个帧不能拼在一起。
	uchar * buffer;

	/// 待写入的帧数据长度。
	ulong	length;

	/// 解码后音频缓冲播放速率，用相对正常速度的倍速表示，比如0.5表示半速播放，
	/// 1.0表示原速播放，2.0表示两倍速播放。如果音频解码器支持音频输出的频率控制，
	/// 就应该根据speed的值做频率控制处理，否则直接静音。
	float speed;

	/// 保留
	int reserved[29];
}AudioDecPacket;

/// 音频解码能力结构，128字节
typedef struct AudioDecCaps
{
	/// 支持的压缩标准的掩码，位序号对应枚举类型AudioEncType的每一个值。
	/// 置位表示支持该枚举值对应的特性，清零表示不支持。
	ulong	types;
	
	/// 前端支持的音频编码格式的组合方式数目，具体参数组合使用getFormatCaps接口函数获取。
	char formatCount;

	/// 保留
	char reserved1[3];

	/// 支持的声音质量增强功能的掩码，位序号对应枚举类型AudioVqeType的每一个值。
	/// 置位表示支持该枚举值对应的特性，清零表示不支持。
	ulong vqeTypes;
	
	/// 保留
	int	reserved[29];
}AudioDecCaps;


/// 音频解码接口，512字节
typedef struct AudioDecoder
{
	/// 底层私有数据
	void *priv;


	/// 增加接口引用
	int (*addRef)(struct AudioDecoder *thiz);


	/// 释放接口
	int (*release)(struct AudioDecoder *thiz);


	/// 获取接口能力特性
	///
	/// \param [in] thiz 本对象指针
	/// \param [out] caps 音频解码能力结构
	/// \return <0 获取失败
	/// \retval 0 获取成功
	int (*getCaps)(struct AudioDecoder *thiz, AudioDecCaps *caps);


	/// 开启音频解码。如果没有混音设备，开启后音频输出自动切换到当前解码通道的音频。
	///
	/// \param [in] thiz 本对象指针
	/// \return <0 开启失败
	/// \retval 0 开启成功
	int (*start)(struct AudioDecoder *thiz);


	/// 停止音频解码。如果没有混音设备，停止后音频输出自动切换到被中断的解码通道的音频。
	/// 如果无解码音频，则输出监视音频。
	///
	/// \param [in] thiz 本对象指针
	/// \return <0 停止失败
	/// \retval 0 停止成功
	int (*stop)(struct AudioDecoder *thiz);


	/// 清空解码后音频缓冲，被阻塞的putFrame将会立即返回。
	/// 
	/// \param [in] thiz 本对象指针
	/// \retval 0  清空成功
	/// \retval <0  清空失败
	int (*flush)(struct AudioDecoder *thiz);


	/// 检查解码后缓冲是否为空，即音频是否已经被全部呈现。
	/// 
	/// \param [in] thiz 视频解码接口指针
	/// \retval 0  非空
	/// \retval 1  已空
	/// \return <0 检查出错
	int (*empty)(struct AudioDecoder *thiz);


	/// 设置音频数据解码的格式。
	///
	/// \param [in] thiz 本对象指针。
	/// \param [in] format 音频解码格式AudioDecFormat指针。
	/// \retval 0  设置成功
	/// \retval <0  设置失败
	int (*setFormat)(struct AudioDecoder *thiz, AudioDecFormat* format);


	/// 填充帧数据到音频解码缓冲，非阻塞操作，如果底层缓冲已满，则返回错误。
	/// 解码后的音频不一定立即播放，底层还需要进行缓冲控制，直到解码后缓冲
	/// 有足够空间，才可以填下次编码数据。
	///
	/// \param [in] thiz 本对象指针
	/// \param [in] packet 解码数据包AudioDecPacket指针
	/// \return <0 填充失败
	/// \retval 0 填充成功
	int (*putPacket)(struct AudioDecoder *thiz, AudioDecPacket *packet);


	/// 设置音频解码的音量。
	///
	/// \param [in] thiz 本对象指针。
	/// \param [in] volume 音量，取值0-100。
	/// \retval 0  设置成功
	/// \retval <0  设置失败
	int (*setVolume)(struct AudioDecoder *thiz, int volume);


	/// 获取音频解码支持的格式列表，应用层必须从支持的列表中选择一项作为setFormat接口的输入参数。
	/// 
	/// \param [in] thiz 本对象指针。
	/// \param [out] formats 格式结构AudioDecFormat数组，数组长度必须足以放下
	///         所有支持的格式列表。支持的格式数目用AudioDecCaps::formatCount表示。
	///			每个AudioEncFormat结构中的type、frequency、depth参数表示一个有效的编码参数组合，
	///			其他参数忽略。
	/// \retval 0  获取成功
	/// \retval <0  获取失败
	int (*getFormatCaps)(struct AudioDecoder *thiz, AudioDecFormat* formats);	

	/// 设置音质增强功能
	///
	/// \param [in] thiz 视频解码接口指针
	/// \param [in] vqeAttr格式结构体指针 AudioOutVqeAttr
	/// \retval 0  成功
	/// \retval <0	失败
	int (*setVqeAttr)(struct AudioDecoder *thiz, AudioOutVqeAttr *vqeAttr);
	
	/// 保留
	int reserved[115];
}AudioDecoder;

/// 音频解码接口描述，128字节
typedef struct AudioDecDesc
{
	AudioSource *source;	///< 解码后生成的音频源
	int	dest;				///< 初始音频输出端口
	int	card;				///< 子卡槽位号，0表示主板，>0表示子卡
	int	channel;		    ///< 音频解码通道号
	int reserved[28];		///< 保留
} AudioDecDesc;


/// 创建音频解码接口
///
/// \param [in] desc 音频解码接口描述结构AudioDecDesc指针
/// \param [out] audioEncoder 音频解码接口指针的指针
/// \retval <0 创建失败
/// \retval 0 创建成功
int PAL_API createAudioDecoder(AudioDecDesc *desc, AudioDecoder** audioDecoder);

/// 获取音频解码通道支持的通道数
///
/// \retval 解码通道数目
int PAL_API getAudioDecoderChannels(void);

#ifdef __cplusplus
}
#endif

#endif //__AUDIO_DEC_API_H__

